<?php

namespace App\Admin\Actions\Post;

use App\Models\Details;
use App\Models\Orders;
use App\Models\RefundLogs;
use EasyWeChat\Factory;
use Encore\Admin\Actions\RowAction;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Encore\Admin\Facades\Admin;

class Refund extends RowAction
{
    public $name = '退款';

    public function handle(Model $model , Request $request)
    {
        if(!in_array($model->status , [2,3,4])){
            return $this->response()->error('该订单不属于退款范围');
        }

        $app = Factory::payment(config('wechat.payment.default'));

        //微信支付订单号
        $transactionSn = $model->transaction_sn;

        //系统订单号
        $refundNumber = $this->refundNumber();

        //订单支付金额
        $totalFee = $model->prices;

        //退款金额
        $refundFee =$request->post('refundFee');

        //退款说明
        $reason = !empty($request->post('reason')) ? $request->post('reason') : '';

        //添加订单退款日志
        $refundLog = RefundLogs::create([
            'user_id' => $model->user_id,
            'admin_id' => Admin::user()->id,
            'money' => $refundFee,
            'note' => $reason,
            'refund_sn' => $refundNumber,
            'order_sn' => $model->order_sn,
            'transaction_sn' => $transactionSn,
        ]);

        if(!$refundLog){
            return $this->response()->error('退款发生错误，请刷新页面后尝试')->refresh();
        }

        // 调用微信退款接口
        $result = $app->refund->byTransactionId($transactionSn, $refundNumber, $totalFee * 100, $refundFee * 100, [
            // 可在此处传入其他参数，详细参数见微信支付文档
            'refund_desc' => $reason,
            'notify_url' => env('APP_URL') . '/wechat/refundCallback'
        ]);
        //记录微信返回的元数据
        $refundLog->original = $result;
        //修改日志信息
        $refundLog->save();
        //退款成功
        if ($result['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
            // 用户是否支付成功
            if (Arr::get($result , 'result_code') === 'SUCCESS') {

                //修改日志退款成成功
                $refundLog->is_success = 1;

                $refundLog->save();

                //订单是否为邀请用户下单返现 是的话 则修改状态
                $detail = Details::where('order_sn' , $model->order_sn)->where('status' , 1)->first();
                if(!empty($detail)){
                    $detail->status = 2;

                    $detail->expect_at = NULL;

                    if(!$detail->save()){
                        return $this->response()->error('该订单关联的返现订单状态为修改完成，返现失败')->refresh();
                    }
                }
                //修改订单为退款状态
                $model->status = 6;
                //记录订单退款时间
                $model->refund_at = date('Y-m-d H:i:s' , time());

                $model->save();

                return $this->response()->success('退款成功,预计1-2分钟到账')->refresh();
             // 用户退款失败
            } elseif (Arr::get($result , 'result_code') === 'FAIL') {
                return $this->response()->warning(Arr::get($result , 'err_code_des'))->refresh();
            }
        } else {
            return $this->response()->error('退款失败，出现未知的错误，请联系开发者...')->refresh();
        }

        return $this->response()->error('退款失败，出现未知的错误')->refresh();
    }


//    public function dialog()
//    {
//        $this->confirm('确定要退款吗?');
//    }

    public function form(){

        $id = $this->getKey();

        $data = Orders::where('id' , $id)->first();

        $this->radio('status', __('返款方式'))->options([0 => '原路退回']);

        $this->text('refundFee', __('退款金额'))->default(number_format($data->prices,2))->help('当前订单最大退款金额 ：'.'<font color="red">'.number_format($data->prices,2).'</font>')->rules("required|numeric|min:0.01|max:$data->prices" , [
            'required' => '退款金额 不能为空',
            'numeric' => '退款金额 必须是数字',
            'min' => '退款金额 不能小于 0.01',
            'max' => '退款金额 不能大于 :max ',
        ]);

        $this->textarea('reason', '退款说明')->help('非必填信息，若填写将展示在下发给用户的退款消息中');
    }

    /**
     * @description: 生成唯一退款订单号
     * @param {type}
     * @return:
     */
    static public function refundNumber()
    {
        $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AB', 'CD', 'EF', 'GH', 'IJ', 'KL', 'MN', 'OP', 'QR', 'ST', 'UV', 'XY', 'ZA');

        return 'TK'.$yCode[intval(date('Y')) - 2021] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
    }

}
